home *** CD-ROM | disk | FTP | other *** search
/ MacGames Sampler / PHT MacGames Bundle.iso / MacSource Folder / Samples from the CD / Editors / emacs / Emacs-1.14b1-sources / sources / unix-emulation-src / stat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-16  |  2.9 KB  |  126 lines  |  [TEXT/EMAC]

  1. /*
  2.  * Copyright (C) 1993, 1994 Marc Parmet.
  3.  * This file is part of the Macintosh port of GNU Emacs.
  4.  *
  5.  * GNU Emacs is distributed in the hope that it will be useful,
  6.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  7.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  8.  * GNU General Public License for more details.
  9.  */
  10.  
  11. #if defined(THINK_C)
  12. #include <MacHeaders>
  13. #else
  14. #include <Types.h>
  15. #include <Memory.h>
  16. #include <Quickdraw.h>
  17. #include <Windows.h>
  18. #include <Errors.h>
  19. #endif
  20.  
  21. #include <Aliases.h>
  22. #include "sys/stat.h"
  23.  
  24. int
  25. number_of_volumes(void)
  26. {
  27.     short err;
  28.     int index;
  29.     HParamBlockRec pb;
  30.     
  31.     index = 1;
  32.     while (1) {
  33.         pb.volumeParam.ioNamePtr = 0L;
  34.         pb.volumeParam.ioVolIndex = index;
  35.         err = PBHGetVInfo(&pb,0);
  36.         if (err) return index-1;
  37.         ++index;
  38.     }
  39. }
  40.  
  41. int
  42. stat_spec_internal(FSSpec *spec,struct stat *st,int stop_at_alias)
  43. {
  44.     short err;
  45.     CInfoPBRec pb;
  46.     Boolean isFolder,wasAliased;
  47.     
  48.     st->st_nlink = 1;
  49.     st->st_ino = 1; // Zero might flag an error somewhere.
  50.     st->st_atime = st->st_ctime = 0;
  51.     st->st_rdev = 0;
  52.  
  53.     pb.dirInfo.ioFDirIndex = 0;
  54.     pb.dirInfo.ioNamePtr = spec->name;
  55.     pb.dirInfo.ioVRefNum = spec->vRefNum;
  56.     pb.dirInfo.ioDrDirID = spec->parID;
  57.     err = PBGetCatInfo(&pb,0);
  58.     if (err) { set_errno(err); return -1; }
  59.  
  60.     if (pb.dirInfo.ioFlAttrib & 0x10) {
  61.         // Looking at a directory or volume.
  62.         st->st_mode = S_IFDIR | 0777;
  63.         st->st_mtime = pb.dirInfo.ioDrMdDat;
  64.         st->st_size = pb.dirInfo.ioDrNmFls;
  65.         st->st_uid = st->st_gid = (pb.dirInfo.ioDrDirID == fsRtDirID) ? 'vol ' : 'fldr';
  66.     }
  67.     else {
  68.         // Looking at either a plain file or an alias.
  69.         if (stop_at_alias) {
  70.             err = ResolveAliasFile(spec,0,&isFolder,&wasAliased);
  71.             if (err == fnfErr && wasAliased)
  72.                 // We allow this case for when the target of an alias cannot be found.
  73.                 ;
  74.             else
  75.                 if (err) { set_errno(err); return -1; };
  76.         }
  77.         else
  78.             wasAliased = 0;
  79.  
  80.         if (wasAliased)
  81.             st->st_mode = S_IFLNK | 0777;
  82.         else
  83.             st->st_mode = S_IFREG |
  84.                 (pb.hFileInfo.ioFlFndrInfo.fdType == 'APPL' ? 0777 : 0666);
  85.  
  86.         // No write permission if file is locked
  87.         if (pb.hFileInfo.ioFlAttrib & 1) st->st_mode &= ~0222;
  88.  
  89.         st->st_mtime = pb.hFileInfo.ioFlMdDat;
  90.         st->st_size = pb.hFileInfo.ioFlLgLen;
  91.         st->st_uid = pb.hFileInfo.ioFlFndrInfo.fdType;
  92.         st->st_gid = pb.hFileInfo.ioFlFndrInfo.fdCreator;
  93.     }
  94.  
  95.     return 0;    
  96. }
  97.  
  98. int
  99. stat_internal(char *filename,struct stat *st,int stop_at_alias)
  100. {
  101.     short err;
  102.     FSSpec spec;
  103.     CInfoPBRec pb;
  104.     Boolean isFolder,wasAliased;
  105.     
  106.     st->st_nlink = 1;
  107.     st->st_ino = 1; // Zero might flag an error somewhere.
  108.     st->st_atime = st->st_ctime = 0;
  109.     st->st_rdev = 0;
  110.  
  111.     err = unixfn2FSSpec_internal(filename,&spec,stop_at_alias);
  112.  
  113.     if (err == nsDrvErr) {
  114.         // Looking at the desktop directory.  We pretend there is such a directory.
  115.         st->st_mode = S_IFDIR | 0777;
  116.         st->st_mtime = 0;
  117.         st->st_size = number_of_volumes();
  118.         st->st_uid = st->st_gid = 'desk';
  119.         return 0;
  120.     }
  121.  
  122.     if (err) { set_errno(err); return -1; }
  123.  
  124.     return stat_spec_internal(&spec,st,stop_at_alias);
  125. }
  126.